﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace AudiPyme.DAL
{
    public static class Matriz_TipoActivosAmenazasCriteriosRiesgoFactory
    {
        //Inserta una relación tipo activo - amenaza - criterio de riesgo en la base de conocimiento
        public static void InsertarMatriz_TipoActivosAmenazasCriteriosRiesgo(Matriz_TipoActivosAmenazasCriteriosRiesgo TipActAmenCritRies)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            agenteBD.AddToMatriz_TipoActivosAmenazasCriteriosRiesgoEstablecer(TipActAmenCritRies);
            agenteBD.SaveChanges();
        }

        //Devuelve una relación tipo activo - amenaza - criterio de riesgo a través de los nombres de los elementos que la conforman
        public static Matriz_TipoActivosAmenazasCriteriosRiesgo BuscarMatriz_TipoActivosAmenazasCriteriosRiesgo(String TipoActivoSelec, String AmenazaSelec, String CriterioRiesgoSelec)
        {
            Matriz_TipoActivosAmenazasCriteriosRiesgo relacion = new Matriz_TipoActivosAmenazasCriteriosRiesgo();
            //Recogemos los Id's asociados al Tipo de Activo, Amenaza y Vulnerabilidad seleccionadas
            int IdTipoActivoSelec = 0;
            int IdAmenazaSelec = 0;
            int IdCriterioRiesgoSelec = 0;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> IdTipoActivo = from TipoActivo in agenteBD.TiposActivosEstablecer
                                           where TipoActivo.TipoActivo == TipoActivoSelec
                                           select TipoActivo.IdTipoActivo;
            foreach (int t in IdTipoActivo)
            {
                IdTipoActivoSelec = t;
            }
            IQueryable<int> IdAmenaza = from Amenazas in agenteBD.AmenazasEstablecer
                                        where Amenazas.Amenaza == AmenazaSelec
                                        select Amenazas.IdAmenaza;
            foreach (int a in IdAmenaza)
            {
                IdAmenazaSelec = a;
            }
            IQueryable<int> IdCriterioRiesgo = from Criterio in agenteBD.CriteriosRiesgoEstablecer
                                               where Criterio.CriterioRiesgo == CriterioRiesgoSelec
                                               select Criterio.IdCriterioRiesgo;
            foreach (int c in IdCriterioRiesgo)
            {
                IdCriterioRiesgoSelec = c;
            }
            relacion.IdTipoActivo = IdTipoActivoSelec;
            relacion.IdAmenaza = IdAmenazaSelec;
            relacion.IdCriterioRiesgo = IdCriterioRiesgoSelec;
            return relacion;
        }

        //Elimina una relación tipo activo - amenaza - criterio de riesgo de la base de conocimiento
        public static void EliminarMatriz_TipoActivosAmenazasCriteriosRiesgo(Matriz_TipoActivosAmenazasCriteriosRiesgo matriz)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<Matriz_TipoActivosAmenazasCriteriosRiesgo> MatrizTipActAmenCritRiesg
                        = from MTAACR in agenteBD.Matriz_TipoActivosAmenazasCriteriosRiesgoEstablecer
                          where MTAACR.IdTipoActivo == matriz.IdTipoActivo && MTAACR.IdAmenaza == matriz.IdAmenaza
                                  && MTAACR.IdCriterioRiesgo == matriz.IdCriterioRiesgo
                          select MTAACR;
            agenteBD.Matriz_TipoActivosAmenazasCriteriosRiesgoEstablecer.DeleteObject(MatrizTipActAmenCritRiesg.First());
            agenteBD.SaveChanges();
        }

        //Indica si una relación tipo activo - amenaza - criterio de riesgo está en la base de conocimiento
        public static bool EstaRelacionMatriz_TipoActivosAmenazasCriterioRiesgo(int IdTipoActivo, int IdAmenaza, int IdCriterioRiesgo)
        {
            Matriz_TipoActivosAmenazasCriteriosRiesgo m = new Matriz_TipoActivosAmenazasCriteriosRiesgo();
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<Matriz_TipoActivosAmenazasCriteriosRiesgo> MatrizTipActAmenCritRiesg
                        = from MTAACR in agenteBD.Matriz_TipoActivosAmenazasCriteriosRiesgoEstablecer
                          where MTAACR.IdTipoActivo == IdTipoActivo && MTAACR.IdAmenaza == IdAmenaza
                                  && MTAACR.IdCriterioRiesgo == IdCriterioRiesgo
                          select MTAACR;
            foreach (Matriz_TipoActivosAmenazasCriteriosRiesgo MatrizTAACR in MatrizTipActAmenCritRiesg)
            {
                m = MatrizTAACR;
            }
            if (m.IdTipoActivo == IdTipoActivo && m.IdAmenaza == IdAmenaza && m.IdCriterioRiesgo == IdCriterioRiesgo)
            {
                return true;
            }
            else
            {
                return false;
            }

        }

        //Método que recoge el número de Relaciones Tipo Activo - Amenaza de la Matriz 
        public static int NumRelacTipAmenCrit()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int nRelac = (from RelacTipActAmenCrit in agenteBD.Matriz_TipoActivosAmenazasCriteriosRiesgoEstablecer
                          where RelacTipActAmenCrit.Actual == true
                          select RelacTipActAmenCrit).Count();
            return nRelac;
        }

        //Método que elimina una lista de relaciones Tipo Activo - Amenaza - Criterio de riesgo de la Matriz
        public static void EliminarInstanciaTipActAmenCrit(int IdTipoActivo, int IdAmenaza, int IdCriterioRiesgo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            Matriz_TipoActivosAmenazasCriteriosRiesgo nuevaInstancia =
                new Matriz_TipoActivosAmenazasCriteriosRiesgo();
            nuevaInstancia.IdTipoActivo = IdTipoActivo;
            nuevaInstancia.IdAmenaza = IdAmenaza;
            nuevaInstancia.IdCriterioRiesgo = IdCriterioRiesgo;
            //Recogemos las instancias de la BD de la empresa que se correspondan con los de la lista
            Matriz_TipoActivosAmenazasCriteriosRiesgo RelacionEliminar
                        = (from RelacMatriz in agenteBD.Matriz_TipoActivosAmenazasCriteriosRiesgoEstablecer
                           where RelacMatriz.IdTipoActivo == nuevaInstancia.IdTipoActivo &&
                                 RelacMatriz.IdAmenaza == nuevaInstancia.IdAmenaza &&
                                 RelacMatriz.IdCriterioRiesgo == nuevaInstancia.IdCriterioRiesgo
                           select RelacMatriz).First();
            RelacionEliminar.Actual = false;
            //Borramos todas las instancias que dependan de esta relacion
            List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LRelTipActAmenCritEliminada = new List<Matriz_TipoActivosAmenazasCriteriosRiesgo>();
            LRelTipActAmenCritEliminada.Add(RelacionEliminar);
            List<InstanciaTiposActivosAmenazasCriteriosRiesgo> LInstPorRelTipActAmenCrit = InstanciaTiposActivosAmenazasCriteriosRiesgoFactory.EliminaInstanciasPorRelacTipActAmenCrit(LRelTipActAmenCritEliminada);
            agenteBD.SaveChanges();
        }

        //Método que hace un borrado lógico de todas las relaciones tipo activo - amenaza - criterio de riesgo dependientes de una lista de Amenazas
        public static List<Matriz_TipoActivosAmenazasCriteriosRiesgo> EliminaRelacionesPorAmenaza(List<Amenazas> LAmenazas)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Por cada amenaza de la lista
            //Lista de aquellas relaciones a las que se le hacen un borrado lógico
            List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LRelacionesEliminadas = new List<Matriz_TipoActivosAmenazasCriteriosRiesgo>();
            foreach (Amenazas A in LAmenazas)
            {
                //Recogemos las Relaciones actuales de la Matriz
                IQueryable<Matriz_TipoActivosAmenazasCriteriosRiesgo> RelacTipActAmenCrit = from Relac in agenteBD.Matriz_TipoActivosAmenazasCriteriosRiesgoEstablecer
                                                                                            where Relac.IdAmenaza == A.IdAmenaza && Relac.Actual == true
                                                                                            select Relac;
                if (RelacTipActAmenCrit.Count() != 0)
                {
                    //Para cada uno actualizamos el Valor Actual a false
                    foreach (Matriz_TipoActivosAmenazasCriteriosRiesgo Relacion in RelacTipActAmenCrit)
                    {
                        Relacion.Actual = false;
                        //Añadimos a la lista de Relaciones Eliminadas
                        LRelacionesEliminadas.Add(Relacion);
                    }
                }
            }
            agenteBD.SaveChanges();
            return LRelacionesEliminadas;
        }

        //Método que hace un borrado lógico de todas las relaciones tipo activo - amenaza - criterio de riesgo dependientes de una lista de Amenazas
        public static List<Matriz_TipoActivosAmenazasCriteriosRiesgo> EliminaRelacionesPorCriterioRiesgo(int IdCriterioRiesgo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Recogemos las relaciones actuales en la Base de Conocimiento
            List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LAmenazas = new List<Matriz_TipoActivosAmenazasCriteriosRiesgo>();
            IQueryable<Matriz_TipoActivosAmenazasCriteriosRiesgo> RelTipActAmenCrit = from Rel in agenteBD.Matriz_TipoActivosAmenazasCriteriosRiesgoEstablecer
                                                                                      where Rel.IdCriterioRiesgo == IdCriterioRiesgo && Rel.Actual == true
                                                                                      select Rel;
            if (RelTipActAmenCrit.Count() != 0)
            {
                //Para cada uno actualizamos el Valor Actual a false
                foreach (Matriz_TipoActivosAmenazasCriteriosRiesgo R in RelTipActAmenCrit)
                {
                    R.Actual = false;
                    LAmenazas.Add(R);
                }
                agenteBD.SaveChanges();
            }
            //Si no había Relaciones dependientes devolvemos la fila vacía
            return LAmenazas;
        }

        //Método que hace un borrado lógico de las Relaciones Tipo Activo - Amenaza - Criterio de Riesgo, según un tipo de activo
        internal static List<Matriz_TipoActivosAmenazasCriteriosRiesgo> EliminaRelacionesPorTipoActivo(int IdTipoActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Recogemos las relaciones actuales en la Base de Conocimiento
            List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LAmenazas = new List<Matriz_TipoActivosAmenazasCriteriosRiesgo>();
            IQueryable<Matriz_TipoActivosAmenazasCriteriosRiesgo> RelTipActAmenCrit = from Rel in agenteBD.Matriz_TipoActivosAmenazasCriteriosRiesgoEstablecer
                                                                                      where Rel.IdTipoActivo == IdTipoActivo && Rel.Actual == true
                                                                                      select Rel;
            if (RelTipActAmenCrit.Count() != 0)
            {
                //Para cada uno actualizamos el Valor Actual a false
                foreach (Matriz_TipoActivosAmenazasCriteriosRiesgo R in RelTipActAmenCrit)
                {
                    R.Actual = false;
                    LAmenazas.Add(R);
                }
                agenteBD.SaveChanges();
            }
            //Si no había Relaciones dependientes devolvemos la fila vacía
            return LAmenazas;
        }


        //Método que restaura las relaciones tipo activo - amenaza - criterio de riesgo a partir de una lista de Ids de amenazas
        internal static List<Matriz_TipoActivosAmenazasCriteriosRiesgo> RestauraRelacionesPorAmenaza(List<int> LAmenazas)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Por cada amenaza de la lista
            //Lista de aquellas relaciones a las que se le hacen un borrado lógico
            List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LRelacionesRestauradas = new List<Matriz_TipoActivosAmenazasCriteriosRiesgo>();
            foreach (int IdAmenaza in LAmenazas)
            {
                //Recogemos las Relaciones actuales de la Matriz
                IQueryable<Matriz_TipoActivosAmenazasCriteriosRiesgo> RelacTipActAmenCrit = from Relac in agenteBD.Matriz_TipoActivosAmenazasCriteriosRiesgoEstablecer
                                                                                            where Relac.IdAmenaza == IdAmenaza
                                                                                            select Relac;
                if (RelacTipActAmenCrit.Count() != 0)
                {
                    //Para cada uno actualizamos el Valor Actual a True
                    foreach (Matriz_TipoActivosAmenazasCriteriosRiesgo Relacion in RelacTipActAmenCrit)
                    {
                        Relacion.Actual = true;
                        //Añadimos a la lista de Relaciones Eliminadas
                        LRelacionesRestauradas.Add(Relacion);
                    }
                }
            }
            agenteBD.SaveChanges();
            return LRelacionesRestauradas;
        }


        //Método que restaura las relaciones tipo activo - amenaza - criterio de riesgo a partir de una lista de Ids de Criterio de Riesgo
        internal static List<Matriz_TipoActivosAmenazasCriteriosRiesgo> RestauraRelacionesPorCriterio(List<int> LCriterioRiesgo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Por cada criterio de riesgo de la lista
            //Lista de aquellas relaciones a las que se le hacen un borrado lógico
            List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LRelacionesRestauradas = new List<Matriz_TipoActivosAmenazasCriteriosRiesgo>();
            foreach (int IdCriterio in LCriterioRiesgo)
            {
                //Recogemos las Relaciones actuales de la Matriz
                IQueryable<Matriz_TipoActivosAmenazasCriteriosRiesgo> RelacTipActAmenCrit = from Relac in agenteBD.Matriz_TipoActivosAmenazasCriteriosRiesgoEstablecer
                                                                                            where Relac.IdCriterioRiesgo == IdCriterio
                                                                                            select Relac;
                if (RelacTipActAmenCrit.Count() != 0)
                {
                    //Para cada uno actualizamos el Valor Actual a True
                    foreach (Matriz_TipoActivosAmenazasCriteriosRiesgo Relacion in RelacTipActAmenCrit)
                    {
                        Relacion.Actual = true;
                        //Añadimos a la lista de Relaciones Eliminadas
                        LRelacionesRestauradas.Add(Relacion);
                    }
                }
            }
            agenteBD.SaveChanges();
            return LRelacionesRestauradas;
        }

        //Método que restaura todas las relaciones tipo activo - amenazas - criterios de riesgo de la base de conocimiento
        //asociadas a una lista de tipos de activos
        internal static List<Matriz_TipoActivosAmenazasCriteriosRiesgo> RestauraRelacionesPorTipoActivo(List<int> LTiposActivos)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Por cada criterio de riesgo de la lista
            //Lista de aquellas relaciones a las que se le hacen un borrado lógico
            List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LRelacionesRestauradas = new List<Matriz_TipoActivosAmenazasCriteriosRiesgo>();
            foreach (int IdTipoActivo in LTiposActivos)
            {
                //Recogemos las Relaciones actuales de la Matriz
                IQueryable<Matriz_TipoActivosAmenazasCriteriosRiesgo> RelacTipActAmenCrit = from Relac in agenteBD.Matriz_TipoActivosAmenazasCriteriosRiesgoEstablecer
                                                                                            where Relac.IdTipoActivo == IdTipoActivo
                                                                                            select Relac;
                if (RelacTipActAmenCrit.Count() != 0)
                {
                    //Para cada uno actualizamos el Valor Actual a True
                    foreach (Matriz_TipoActivosAmenazasCriteriosRiesgo Relacion in RelacTipActAmenCrit)
                    {
                        Relacion.Actual = true;
                        //Añadimos a la lista de Relaciones Eliminadas
                        LRelacionesRestauradas.Add(Relacion);
                    }
                }
            }
            agenteBD.SaveChanges();
            return LRelacionesRestauradas;
        }

        //Indica si una relación tipo activo - amenaza - criterio de riesgo está en la base de conocimiento
        public static bool EstaRelacion_TipoActivo_Amenaza_CriterioRiesgo(string TipoActivoSelec, string AmenazaSelec, string CriterioSelec)
        {
            bool esta = false;
            ModeloContainer agenteBD = new ModeloContainer();
            int IdTipoActivoSelec = TiposActivosFactory.BuscarIdTipoActivo(TipoActivoSelec);
            int IdAmenazaSelec = AmenazasFactory.BuscarIdAmenaza(AmenazaSelec);
            int IdCriterioSelec = CriteriosRiesgoFactory.BuscarIdCriterioRiesgo(CriterioSelec);
            IQueryable<Matriz_TipoActivosAmenazasCriteriosRiesgo> RelacionEncontrada = from MatrTipAmenCrit in agenteBD.Matriz_TipoActivosAmenazasCriteriosRiesgoEstablecer
                                                                                       where MatrTipAmenCrit.IdTipoActivo == IdTipoActivoSelec && MatrTipAmenCrit.IdAmenaza == IdAmenazaSelec &&
                                                                                       MatrTipAmenCrit.IdCriterioRiesgo == IdCriterioSelec
                                                                                       select MatrTipAmenCrit;
            //Si está la relación y con el campo actual a true se devuelve un true
            if (RelacionEncontrada.Count() != 0 && RelacionEncontrada.First().Actual == true)
            {
                esta = true;
            }
            return esta;
        }

        //Inserta una relación tipo activo - amenaza - criterio de riesgo a través de los nombres de los elementos que la componen
        public static void Inserta_Relacion_TipoActivo_Amenaza_Criterio(string TipoActivoSelec, string AmenazaSelec, string CriterioRiesgoSelec)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            Matriz_TipoActivosAmenazasCriteriosRiesgo matriz = new Matriz_TipoActivosAmenazasCriteriosRiesgo();
            //Recogemos los Id's asociados a las relaciones seleccionadas
            int IdTipoActivoSelec = TiposActivosFactory.BuscarIdTipoActivo(TipoActivoSelec);
            int IdAmenazaSelec = AmenazasFactory.BuscarIdAmenaza(AmenazaSelec);
            int IdCriterioSelec = CriteriosRiesgoFactory.BuscarIdCriterioRiesgo(CriterioRiesgoSelec);
            IQueryable<Matriz_TipoActivosAmenazasCriteriosRiesgo> Relacion = from Matriz in agenteBD.Matriz_TipoActivosAmenazasCriteriosRiesgoEstablecer
                                                                             where Matriz.IdTipoActivo == IdTipoActivoSelec && Matriz.IdAmenaza == IdAmenazaSelec &&
                                                                                   Matriz.IdCriterioRiesgo == IdCriterioSelec
                                                                             select Matriz;
            //Si la relacion no existe en la base de datos
            if (Relacion.Count() == 0)
            {
                //se inserta
                Matriz_TipoActivosAmenazasCriteriosRiesgo nuevaRelacion = new Matriz_TipoActivosAmenazasCriteriosRiesgo();
                nuevaRelacion.IdTipoActivo = IdTipoActivoSelec;
                nuevaRelacion.IdAmenaza = IdAmenazaSelec;
                nuevaRelacion.IdCriterioRiesgo = IdCriterioSelec;
                nuevaRelacion.Actual = true;
                InsertarMatriz_TipoActivosAmenazasCriteriosRiesgo(nuevaRelacion);
            }
            //Si existe se actualiza su valor Actual a true
            else
            {
                Relacion.First().Actual = true;
                agenteBD.SaveChanges();
            }
        }

        //Método que restaura un conjunto de relaciones tipo activo - amenaza - criterio de riesgo en la base de conocimiento
        public static void RestauraConocimientoPorRelacion(List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LTiposAmenazasCriterios)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Lista de IdsAmenazas e IdTiposAmenazas asociadas
            List<int> LIdsTiposActivos = new List<int>();
            List<int> LIdsAmenazas = new List<int>();
            List<int> LIdsTipoAmenazas = new List<int>();
            List<int> LIdsCriterios = new List<int>();
            //Recorremos las relaciones seleccionadas 
            foreach (Matriz_TipoActivosAmenazasCriteriosRiesgo Relacion in LTiposAmenazasCriterios)
            {
                Matriz_TipoActivosAmenazasCriteriosRiesgo RelacionRestaura = (from MatrizTipAmenCrit in agenteBD.Matriz_TipoActivosAmenazasCriteriosRiesgoEstablecer
                                                                              where MatrizTipAmenCrit.IdTipoActivo == Relacion.IdTipoActivo &&
                                                                                    MatrizTipAmenCrit.IdAmenaza == Relacion.IdAmenaza &&
                                                                                    MatrizTipAmenCrit.IdCriterioRiesgo == Relacion.IdCriterioRiesgo
                                                                              select MatrizTipAmenCrit).Single();
                RelacionRestaura.Actual = true;
                //Recogemos los Ids distintos de Tipos de Activos
                if (!LIdsTiposActivos.Contains(Relacion.IdTipoActivo))
                    LIdsTiposActivos.Add(Relacion.IdTipoActivo);
                //Recogemos los Ids distintos de Amenazas
                if (!LIdsAmenazas.Contains(Relacion.IdAmenaza))
                    LIdsAmenazas.Add(Relacion.IdAmenaza);
                int IdTipoAmenaza = TiposAmenazasFactory.IdTipoAmenaza(Relacion.IdAmenaza);
                if (!LIdsTipoAmenazas.Contains(IdTipoAmenaza))
                    LIdsTipoAmenazas.Add(IdTipoAmenaza);
                //Recogemos los Ids distintos de Criterios
                if (!LIdsCriterios.Contains(Relacion.IdCriterioRiesgo))
                    LIdsCriterios.Add(Relacion.IdCriterioRiesgo);
            }

            //Restauramos los Tipos de Activos y Vulnerabilidades recogidas a través de sus Ids
            TiposActivosFactory.RestauraTipoActivoPorRelaciones(LIdsTiposActivos);
            AmenazasFactory.RestauraAmenazaPorRelaciones(LIdsAmenazas);
            TiposAmenazasFactory.RestauraTipoAmenazaPorRelaciones(LIdsTipoAmenazas);
            CriteriosRiesgoFactory.RestauraCriterioPorRelaciones(LIdsCriterios);
            //Restauramos las Instancias Tipo Activo - Vulnerabilidad asociadas a esas relaciones
            InstanciaTiposActivosAmenazasCriteriosRiesgoFactory.RestauraInstanciasPorRelacTipActAmenCrit(LTiposAmenazasCriterios);
            agenteBD.SaveChanges();
        }
    }
}
